﻿using Fine.TestUtils;
using NUnit.Framework;



namespace Fine.Collections.Cont
{
    [TestFixture]
    public class ArrMatrix_test
    {

        [Test]
        public void Test_Constructor()
        {
            var m = new ArrMatrix<byte>(1, 3, 1, 3);

            m.FirstX   ._equals_(1);
            m.LastX    ._equals_(3);
            m.FirstY   ._equals_(1);
            m.LastY    ._equals_(3);
            m.SizeX    ._equals_(3);
            m.SizeY    ._equals_(3);
        }


        [Test]
        public void Test_Basic()
        {
            var m = new ArrMatrix<long>(1, 3, 1, 3);

            int v = 0;
            for (int i = 1; i <= 3; i++)
                for (int j = 1; j <= 3; j++)
                    m[i, j] = ++v;

            m[1,1] ._equals_(1);
            m[1,2] ._equals_(2);
            m[1,3] ._equals_(3);
            m[2,1] ._equals_(4);
            m[2,2] ._equals_(5);
            m[2,3] ._equals_(6);
            m[3,1] ._equals_(7);
            m[3,2] ._equals_(8);
            m[3,3] ._equals_(9);
        }


        [Test]
        public void Test_AddRow()
        {
            var m = new ArrMatrix<long>(1, 3, 1, 3);

            int v = 0;
            for (int i = 1; i <= 3; i++)
                for (int j = 1; j <= 3; j++)
                    m[i, j] = ++v;

            m.AddRow();

            m[1,1] ._equals_(1);
            m[1,2] ._equals_(2);
            m[1,3] ._equals_(3);
            m[2,1] ._equals_(4);
            m[2,2] ._equals_(5);
            m[2,3] ._equals_(6);
            m[3,1] ._equals_(7);
            m[3,2] ._equals_(8);
            m[3,3] ._equals_(9);

            m[4,1] ._equals_(0);
            m[4,2] ._equals_(0);
            m[4,3] ._equals_(0);
        }


        [Test]
        public void Test_MoveRow_Forward()
        {
            var m = PrepareMatrix(5, 3);

            m.MoveRow(2, 4);

            m.RowAsArray(1)  ._array_(11,12,13);
            m.RowAsArray(2)  ._array_(31,32,33);
            m.RowAsArray(3)  ._array_(41,42,43);
            m.RowAsArray(4)  ._array_(21,22,23);
            m.RowAsArray(5)  ._array_(51,52,53);
        }


        [Test]
        public void Test_MoveRow_Backward()
        {
            var m = PrepareMatrix(5, 3);

            m.MoveRow(4, 2);

            m.RowAsArray(1)  ._array_(11,12,13);
            m.RowAsArray(2)  ._array_(41,42,43);
            m.RowAsArray(3)  ._array_(21,22,23);
            m.RowAsArray(4)  ._array_(31,32,33);
            m.RowAsArray(5)  ._array_(51,52,53);
        }


        [Test]
        public void Test_MoveRow_Same()
        {
            var m = PrepareMatrix(5, 3);

            m.MoveRow(3, 3); // nothing should be changed

            m.RowAsArray(1)  ._array_(11,12,13);
            m.RowAsArray(2)  ._array_(21,22,23);
            m.RowAsArray(3)  ._array_(31,32,33);
            m.RowAsArray(4)  ._array_(41,42,43);
            m.RowAsArray(5)  ._array_(51,52,53);
        }


        [Test]
        public void Test_RowAsArray()
        {
            var m = PrepareMatrix(3, 3);

            m.RowAsArray(1)  ._array_(11,12,13);
            m.RowAsArray(2)  ._array_(21,22,23);
            m.RowAsArray(3)  ._array_(31,32,33);
        }


        [Test]
        public void Test_ColumnAsArray()
        {
            var m = PrepareMatrix(3, 3);

            m.ColumnAsArray(1)  ._array_(11,21,31);
            m.ColumnAsArray(2)  ._array_(12,22,32);
            m.ColumnAsArray(3)  ._array_(13,23,33);
        }


        [Test]
        public void Test_Row_Basic()
        {
            var m = PrepareMatrix(3, 3);
            var row = m.Row(2);

            row.FirstIndex  ._equals_(1);
            row.LastIndex   ._equals_(3);
            row.First       ._equals_(21);
            row.Last        ._equals_(23);

            row[1]          ._equals_(21);
            row[2]          ._equals_(22);
            row[3]          ._equals_(23);
        }


        [Test]
        public void Test_Row_Iterator()
        {
            var m = PrepareMatrix(3, 3);
            var row = m.Row(2);

            var it = row.TakeIterator();

            it.Next()    ._true_();
            it.Current   ._equals_(21);
            it.Next()    ._true_();
            it.Current   ._equals_(22);
            it.Next()    ._true_();
            it.Current   ._equals_(23);
            it.Next()    ._false_();
        }


        private ArrMatrix<int> PrepareMatrix(int y, int x) 
        {
            var m = new ArrMatrix<int>(1, y, 1, x);

            for (int i = 1; i <= y; i++)
                for (int j = 1; j <= x; j++)
                    m[i, j] = i*10 + j;

            return m;
        }


    }
}
